package com.zzyl.serve.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.LocalDateTimeUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.huaweicloud.sdk.iotda.v5.IoTDAClient;
import com.huaweicloud.sdk.iotda.v5.model.DeviceShadowData;
import com.huaweicloud.sdk.iotda.v5.model.ShowDeviceShadowRequest;
import com.huaweicloud.sdk.iotda.v5.model.ShowDeviceShadowResponse;
import com.zzyl.common.constant.HttpStatus;
import com.zzyl.common.exception.base.BaseException;
import com.zzyl.common.utils.DateUtils;
import com.zzyl.common.utils.UserThreadLocal;
import com.zzyl.framework.config.properties.HuaWeiIotConfigProperties;
import com.zzyl.framework.web.service.TokenService;
import com.zzyl.serve.domain.*;
import com.zzyl.serve.dto.ElderFamilyMemberDto;
import com.zzyl.serve.dto.ElderInfoDTO;
import com.zzyl.serve.dto.UserLoginRequestDto;
import com.zzyl.serve.mapper.*;
import com.zzyl.serve.service.IFamilyMemberService;
import com.zzyl.serve.service.WechatService;
import com.zzyl.serve.vo.*;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.ZoneOffset;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 老人家属Service业务层处理
 *
 * @author itheima
 * @date 2025-03-12
 */
@Service
@RequiredArgsConstructor
@Slf4j
public class FamilyMemberServiceImpl extends ServiceImpl<FamilyMemberMapper, FamilyMember> implements IFamilyMemberService {
    private final RoomMapper roomMapper;
    private final BedMapper bedMapper;
    private final FamilyMemberMapper familyMemberMapper;
    private final WechatService webschatService;
    private final TokenService tokenService;
    private final ElderServiceImpl elderService;
    private final ElderMapper elderMapper;
    private final ElderFamilyRelationMapper elderFamilyRelationMapper;
    private final DeviceMapper deviceMapper;
    private final DeviceDataMapper deviceDataMapper;
    private HuaWeiIotConfigProperties huaWeiIotConfigProperties;
    /**
     * 查询老人家属
     *
     * @param id 老人家属主键
     * @return 老人家属
     */
    @Override
    public FamilyMember selectFamilyMemberById(Long id) {
        return getById(id);
    }

    /**
     * 查询老人家属列表
     *
     * @param familyMember 老人家属
     * @return 老人家属
     */
    @Override
    public List<FamilyMember> selectFamilyMemberList(FamilyMember familyMember) {
        return familyMemberMapper.selectFamilyMemberList(familyMember);
    }

    /**
     * 新增老人家属
     *
     * @param familyMember 老人家属
     * @return 结果
     */
    @Override
    public int insertFamilyMember(FamilyMember familyMember) {
        return save(familyMember) ? 1 : 0;
    }

    /**
     * 修改老人家属
     *
     * @param familyMember 老人家属
     * @return 结果
     */
    @Override
    public int updateFamilyMember(FamilyMember familyMember) {
        return updateById(familyMember) ? 1 : 0;
    }

    /**
     * 批量删除老人家属
     *
     * @param ids 需要删除的老人家属主键
     * @return 结果
     */
    @Override
    public int deleteFamilyMemberByIds(Long[] ids) {
        return removeByIds(Arrays.asList(ids)) ? 1 : 0;
    }

    /**
     * 删除老人家属信息
     *
     * @param id 老人家属主键
     * @return 结果
     */
    @Override
    public int deleteFamilyMemberById(Long id) {
        return removeById(id) ? 1 : 0;
    }

    /**
     * 小程序端 用户登录的逻辑处理
     *
     * @param dto
     * @return
     */
    @Override
    public LoginVo login(UserLoginRequestDto dto) {


        //1.根据code调用微信api获取apenId,并用常量存储
        String openid = webschatService.getOpenid(dto.getCode());


        //2.根据openId查询数据库获取用户信息family_member表
        FamilyMember familyMember = getOne(
                new LambdaQueryWrapper<FamilyMember>()
                        .eq(FamilyMember::getOpenId, openid)
        );

        //3.调用微信api获取用户绑定手机号
        String phone = webschatService.getPhone(dto.getPhoneCode());

        //4.判断用户信息是否存在，如果不存在，则新增family_member表
        //5.存在则 修改family_member表数据
        if (ObjectUtil.isNull(familyMember)) {
            // 新用户
            familyMember = new FamilyMember();
            familyMember.setPhone(phone);
            familyMember.setOpenId(openid);

            // 设置初始随机名称
            familyMember.setName("花开富贵" + DateUtils.getTime());

            save(familyMember);

        } else {
            // 老用户
            familyMember.setPhone(phone);
            updateById(familyMember);
        }


        //6.将用户id存入token中，并返回数据给前端
        Map<String, Object> claims = new HashMap<>();
        claims.put("userId", familyMember.getId());
        claims.put("nickName", familyMember.getName());

        String token = tokenService.createToken(claims);
        LoginVo loginVo = new LoginVo();
        loginVo.setToken(token);
        loginVo.setNickName(familyMember.getName());
        return loginVo;
    }



    @Override
    public void addElderMember(ElderInfoDTO dto) {

        Long familyMemberId = UserThreadLocal.getUserId();
//根据dto中的身份证号查询该老人是否已经被绑定
        Elder elder = elderMapper.selectOne(Wrappers.lambdaQuery(Elder.class)
                .eq(Elder::getIdCardNo, dto.getIdCard()));
        if (ObjectUtil.isEmpty(elder)) {
            //抛出异常老人不存在
            throw new RuntimeException("老人不存在");
        }
//根据老人id查询老人和家属关系
        ElderFamilyRelation elderFamilyRelation = elderFamilyRelationMapper.selectOne(Wrappers.lambdaQuery(ElderFamilyRelation.class)
                .eq(ElderFamilyRelation::getElderId, elder.getId()));
        if (ObjectUtil.isNotEmpty(elderFamilyRelation)) {
            throw new RuntimeException("老人已绑定");
        }
//根据familyMemberId查询性别
        FamilyMember familyMember = familyMemberMapper.selectById(familyMemberId);
        Integer sex = familyMember.getGender();
        if (ObjectUtil.isEmpty(sex)) {
            sex = 1;
        }
        ElderFamilyRelation elderFamilyRelation1 = ElderFamilyRelation.builder()
                .elderId(elder.getId())
                .familyMemberId(familyMemberId)
                .relationType(sex.toString())
                .remark(dto.getRemark())
                .createTime(DateUtils.getNowDate())
                .build();
        int insert = elderFamilyRelationMapper.insert(elderFamilyRelation1);


    }

    @Override
    public List<ElderFamilyBindVO> listByPage(Integer pageNum, Integer pageSize) {
        PageHelper.startPage(pageNum, pageSize);
        Long familyMemberId = UserThreadLocal.getUserId();
        //构建返回vo
        List<ElderFamilyBindVO> list = new ArrayList<>();
        //从关系表中查
        List<ElderFamilyRelation> efList = elderFamilyRelationMapper.selectAllElderByFamilyMemberId(familyMemberId);
        //循环取出老人id
        List<Long> elderIds = new ArrayList<>();
        for (ElderFamilyRelation elderFamilyRelation : efList) {
            elderIds.add(elderFamilyRelation.getElderId());
        }

        for (Long elderId : elderIds) {
            list.add(getElderFamilyBindVO(elderId));
        }

        return list;
    }

    public ElderFamilyBindVO getElderFamilyBindVO(Long elderId) {
        ElderFamilyBindVO elderFamilyBindVO = new ElderFamilyBindVO();
        //查询出有关系的所有信息
        Elder elder = elderMapper.selectById(elderId);
        ElderFamilyRelation elderFamilyRelation = elderFamilyRelationMapper.selectOne(new LambdaQueryWrapper<ElderFamilyRelation>().eq(ElderFamilyRelation::getElderId, elderId));
        //根据老人表中的bedid查
        Bed bed = bedMapper.selectOne(new LambdaQueryWrapper<Bed>().eq(Bed::getBedNumber, elder.getBedNumber()));
        Room room = roomMapper.selectOne(new LambdaQueryWrapper<Room>().eq(Room::getId, bed.getRoomId()));
        LambdaQueryWrapper<Device> deviceLambdaQueryWrapper = new LambdaQueryWrapper<>();
        log.info("=======老人id{}", elderId);
        deviceLambdaQueryWrapper.eq(Device::getLocationType, 0);
        deviceLambdaQueryWrapper.eq(Device::getBindingLocation, elderId);
        Device device = deviceMapper.selectOne(deviceLambdaQueryWrapper);
        //构建返回值
        elderFamilyBindVO.setMid(elderFamilyRelation.getId());
        elderFamilyBindVO.setMremark(elderFamilyRelation.getRemark());
        elderFamilyBindVO.setElderId(elderId);
        elderFamilyBindVO.setName(elder.getName());
        elderFamilyBindVO.setImage(elder.getImage());
        elderFamilyBindVO.setBedNumber(elder.getBedNumber());
        elderFamilyBindVO.setTypeName(room.getTypeName());
        if (ObjectUtil.isNotEmpty(device)) {
            elderFamilyBindVO.setIotId(device.getIotId());
            elderFamilyBindVO.setDeviceName(device.getDeviceName());
            elderFamilyBindVO.setProductKey(device.getProductKey());
        }
        return elderFamilyBindVO;
    }


    @Resource
    private IoTDAClient client;
    /**
     * 根据设备id查询设备属性
     *
     * @see
     */
    @Override
    public List<?> queryServiceProperties(String iotId) {
        ShowDeviceShadowRequest request = new ShowDeviceShadowRequest();
        request.setDeviceId(iotId);
        ShowDeviceShadowResponse response = client.showDeviceShadow(request);
        if (response.getHttpStatusCode() != HttpStatus.SUCCESS) {
            throw new BaseException("物联网接口-查询设备上报数据, 调用失败");
        }
        List<DeviceShadowData> shadowData = response.getShadow();
        if (CollUtil.isEmpty(shadowData)) {
            return Collections.emptyList();
        }

        JSONObject jsonObject = JSONUtil.parseObj(shadowData.get(0).getReported().getProperties());
        List<Map<String, Object>> list = new ArrayList<>();
        LocalDateTime activeTime = LocalDateTimeUtil.parse(shadowData.get(0).getReported().getEventTime(),
                "yyyyMMdd'T'HHmmss'Z'");
        LocalDateTime eventTime = activeTime.atZone(ZoneId.from(ZoneOffset.UTC))
                .withZoneSameInstant(ZoneId.of("Asia/Shanghai"))
                .toLocalDateTime();
        jsonObject.forEach((k, v) -> {
            Map<String, Object> map = new HashMap<>();
            map.put("functionId", k);
            map.put("eventTime", eventTime);
            map.put("value", v);
            list.add(map);
        });
        return list;
    }

    @Override
    public List<?> queryDeviceDataListByDay(String iotId, String functionId, Long startTime, Long endTime) {
        //把时间戳转换成时间
        LocalDateTime startDateTime = LocalDateTimeUtil.of(startTime);
        LocalDateTime endDateTime = LocalDateTimeUtil.of(endTime);
        List<Map<String, Object>> data = deviceDataMapper.selectDeviceDataListByDay(iotId, functionId, startDateTime, endDateTime);
        return data;
    }

    @Override
    public List<?> queryDeviceDataListByWeek(String iotId, String functionId, Long startTime, Long endTime) {
        LocalDateTime startDateTime = LocalDateTimeUtil.of(startTime);
        LocalDateTime endDateTime = LocalDateTimeUtil.of(endTime);
        List<Map<String, Object>> data = deviceDataMapper.selectDeviceDataListByWeek(iotId, functionId, startDateTime, endDateTime);
        return data;
    }
}
